package cn.schoolwow.quickdao.module.database.ddl.action.service.column;

import cn.schoolwow.quickdao.domain.QuickDAOConfig;
import cn.schoolwow.quickdao.domain.database.parent.DatabaseType;
import cn.schoolwow.quickdao.domain.entity.Entity;
import cn.schoolwow.quickdao.module.database.parent.flow.executor.ExecuteUpdateConnectionFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;

public class EnableForeignConstraintCheckFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        boolean enable = (boolean) flowContext.checkData("enable");
        if(enable){
            enableForeignKey(flowContext);
        }else{
            disableForeignKey(flowContext);
        }
    }

    @Override
    public String name() {
        return "开启/关闭外键约束检查";
    }

    private void enableForeignKey(FlowContext flowContext){
        DatabaseType databaseType = flowContext.checkInstanceData(DatabaseType.class);
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);

        switch (databaseType){
            case SQLite:{
                flowContext.putTemporaryData("sql", "PRAGMA foreign_keys = true;");
            }break;
            case Mysql:
            case MariaDB:{
                flowContext.putTemporaryData("sql", "set foreign_key_checks = 1;");
            }break;
            case Postgresql:{
                String tableName = (String) flowContext.getData("tableName");
                if(null==tableName){
                    StringBuilder sqlBuilder = new StringBuilder();
                    for(Entity entity:quickDAOConfig.databaseContext.entityMap.values()){
                        if(!entity.foreignKeyProperties.isEmpty()){
                            sqlBuilder.append("alter table \""+entity.tableName+"\" enable trigger all;");
                        }
                        flowContext.putTemporaryData("sql", sqlBuilder.toString());
                    }
                }else{
                    flowContext.putTemporaryData("sql", "alter table \""+tableName+"\" enable trigger all;");
                }
            }break;
            default:{
                flowContext.broken("当前数据库不支持开启/关闭外键约束!");
            }
        }
        flowContext.startFlow(new ExecuteUpdateConnectionFlow())
                .putTemporaryData("name", "启用外键约束检查")
                .execute();
    }

    private void disableForeignKey(FlowContext flowContext){
        DatabaseType databaseType = flowContext.checkInstanceData(DatabaseType.class);
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);

        switch (databaseType){
            case SQLite:{
                flowContext.putTemporaryData("sql", "PRAGMA foreign_keys = false;");
            }break;
            case Mysql:
            case MariaDB:{
                flowContext.putTemporaryData("sql", "set foreign_key_checks = 0;");
            }break;
            case Postgresql:{
                String tableName = (String) flowContext.getData("tableName");
                if(null==tableName){
                    StringBuilder sqlBuilder = new StringBuilder();
                    for(Entity entity:quickDAOConfig.databaseContext.entityMap.values()){
                        if(!entity.foreignKeyProperties.isEmpty()){
                            sqlBuilder.append("alter table \""+entity.tableName+"\" disable trigger all;");
                        }
                        flowContext.putTemporaryData("sql", sqlBuilder.toString());
                    }
                }else{
                    flowContext.putTemporaryData("sql", "alter table \""+tableName+"\" disable trigger all;");
                }
            }break;
            default:{
                flowContext.broken("当前数据库不支持开启/关闭外键约束!");
            }
        }
        flowContext.startFlow(new ExecuteUpdateConnectionFlow())
                .putTemporaryData("name", "禁用外键约束检查")
                .execute();
    }

}


